1 <?php
2
3     #########################################################
4     
/*
5     ~~~~~~ LIST OF FUNCTIONS ~~~~~~
6         getTableList() -- returns an associative array (tableName => tableData, tableData
is array(tableCaption, tableDescription, tableIcon)) of tables accessible by current user
7         get_table_groups() -- returns an associative array (table_group => tables_array)
8         logInMember() -- checks POST login. If not valid, redirects to index.php,
else returns TRUE
9         getTablePermissions($tn) -- returns an array of permissions allowed
for logged member to given table (allowAccess, allowInsert, allowView, allowEdit, allowDelete) -- allowAccess is set to true if any access level is allowed
10         get_sql_fields($tn) -- returns the SELECT part of the table view query
11         get_sql_from($tn[,
true]) -- returns the FROM part of the table view query, with full joins, optionally skipping permissions if true passed as 2nd param.
12         get_joined_record($table, $id[,
true]) -- returns assoc array of record values for given PK value of given table, with full joins, optionally skipping permissions if true passed as 3rd param.
13         get_defaults($table) -- returns assoc array of table fields
as array keys and default values (or empty), excluding automatic values as array values
14         htmlUserBar() -- returns html code
for displaying user login status to be used on top of pages.
15         showNotifications($msg, $
class) -- returns html code for displaying a notification. If no parameters provided, processes the GET request for possible notifications.
16         parseMySQLDate(a, b) -- returns a
if valid mysql date, or b if valid mysql date, or today if b is true, or empty if b is false.
17         parseCode(code) -- calculates and returns special values to be inserted
in automatic fields.
18         addFilter(i, filterAnd, filterField, filterOperator, filterValue) -- enforce a filter over data
19         clearFilters() -- clear all filters
20         loadView($view, $data) -- passes $data to templates/{$view}.php and returns the output
21         loadTable($table, $data) -- loads table template, passing $data to it
22         filterDropdownBy($filterable, $filterers, $parentFilterers, $parentPKField, $parentCaption, $parentTable, &$filterableCombo) -- applies cascading drop-downs
for a lookup field, returns js code to be inserted into the page
23         br2nl($text) -- replaces all variations of HTML <br> tags with a
new line character
24         htmlspecialchars_decode($text) -- inverse of htmlspecialchars()
25         entitiesToUTF8($text) -- convert unicode entities (e.g. &#
1234;) to actual UTF8 characters, requires multibyte string PHP extension
26         func_get_args_byref() -- returns an array of arguments passed to a function,
by reference
27         permissions_sql($table, $level) -- returns an array containing the FROM and WHERE additions
for applying permissions to an SQL query
28         error_message($msg[, $back_url]) -- returns html code
for a styled error message .. pass explicit false in second param to suppress back button
29         toMySQLDate($formattedDate, $sep = datalist_date_separator, $ord = datalist_date_format)
30         reIndex(&$arr) -- returns a copy of the given array, with keys replaced
by 1-based numeric indices, and values replaced by original keys
31         get_embed($provider, $url[, $width, $height, $retrieve]) -- returns embed code
for a given url (supported providers: youtube, googlemap)
32         check_record_permission($table, $id, $perm =
'view') -- returns true if current user has the specified permission $perm ('view', 'edit' or 'delete') for the given recors, false otherwise
33         NavMenus($options) -- returns the HTML code
for the top navigation menus. $options is not implemented currently.
34         StyleSheet() -- returns the HTML code
for included style sheet files to be placed in the <head> section.
35         getUploadDir($dir) --
if dir is empty, returns upload dir configured in defaultLang.php, else returns $dir.
36         PrepareUploadedFile($FieldName, $MaxSize, $FileTypes=
'jpg|jpeg|gif|png', $NoRename=false, $dir="") -- validates and moves uploaded file for given $FieldName into the given $dir (or the default one if empty)
37         get_home_links($homeLinks, $default_classes, $tgroup) -- process $homeLinks array and
return custom links for homepage. Applies $default_classes to links if links have classes defined, and filters links by $tgroup (using '*' matches all table_group values)
38         quick_search_html($search_term, $label, $separate_dv =
true) -- returns HTML code for the quick search box.
39     ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
40     */

41
42     #########################################################
43
44     function getTableList($skip_authentication =
false){
45         $arrAccessTables = array();
46         $arrTables = array(
47             
/* 'table_name' => ['table caption', 'homepage description', 'icon', 'table group name'] */
48             
'schools' => array('Lớp học', '', 'resources/table_icons/building.png', 'None'),
49             
'departments' => array('Môn học', '', 'resources/table_icons/chart_organisation.png', 'None'),
50             
'class_time_table' => array('Lịch học', '', 'resources/table_icons/blackboard_drawing.png', 'None'),
51             
'exam_time_table' => array('Lịch thi', '', 'resources/table_icons/books.png', 'None'),
52             
'personal_time_table' => array('Lịch cá nhân', '', 'resources/table_icons/clock_.png', 'None'),
53             
'student_details' => array('Chi tiết sinh viên', '', 'resources/table_icons/administrator.png', 'None'),
54             
'notices' => array('Thông báo', '', 'resources/table_icons/clipboard_empty.png', 'None')
55         );
56         
if($skip_authentication || getLoggedAdmin()) return $arrTables;
57
58         
if(is_array($arrTables)){
59             
foreach($arrTables as $tn => $tc){
60                 $arrPerm = getTablePermissions($tn);
61                 
if($arrPerm[0]){
62                     $arrAccessTables[$tn] = $tc;
63                 }
64             }
65         }
66
67         
return $arrAccessTables;
68     }
69
70     #########################################################
71
72     function get_table_groups($skip_authentication =
false){
73         $tables = getTableList($skip_authentication);
74         $all_groups = array(
'None');
75
76         $groups = array();
77         
foreach($all_groups as $grp){
78             
foreach($tables as $tn => $td){
79                 
if($td[3] && $td[3] == $grp) $groups[$grp][] = $tn;
80                 
if(!$td[3]) $groups[0][] = $tn;
81             }
82         }
83
84         
return $groups;
85     }
86
87     #########################################################
88
89     function getTablePermissions($tn){
90         
static $table_permissions = array();
91         
if(isset($table_permissions[$tn])) return $table_permissions[$tn];
92
93         $groupID = getLoggedGroupID();
94         $memberID = makeSafe(getLoggedMemberID());
95         $res_group = sql(
"select tableName, allowInsert, allowView, allowEdit, allowDelete from membership_grouppermissions where groupID='{$groupID}'", $eo);
96         $res_user = sql(
"select tableName, allowInsert, allowView, allowEdit, allowDelete from membership_userpermissions where lcase(memberID)='{$memberID}'", $eo);
97
98         
while($row = db_fetch_assoc($res_group)){
99             $table_permissions[$row[
'tableName']] = array(
100                 
1 => intval($row['allowInsert']),
101                 
2 => intval($row['allowView']),
102                 
3 => intval($row['allowEdit']),
103                 
4 => intval($row['allowDelete']),
104                 
'insert' => intval($row['allowInsert']),
105                 
'view' => intval($row['allowView']),
106                 
'edit' => intval($row['allowEdit']),
107                 
'delete' => intval($row['allowDelete'])
108             );
109         }
110
111         
// user-specific permissions, if specified, overwrite his group permissions
112         
while($row = db_fetch_assoc($res_user)){
113             $table_permissions[$row[
'tableName']] = array(
114                 
1 => intval($row['allowInsert']),
115                 
2 => intval($row['allowView']),
116                 
3 => intval($row['allowEdit']),
117                 
4 => intval($row['allowDelete']),
118                 
'insert' => intval($row['allowInsert']),
119                 
'view' => intval($row['allowView']),
120                 
'edit' => intval($row['allowEdit']),
121                 
'delete' => intval($row['allowDelete'])
122             );
123         }
124
125         
// if user has any type of access, set 'access' flag
126         
foreach($table_permissions as $t => $p){
127             $table_permissions[$t][
'access'] = $table_permissions[$t][0] = false;
128
129             
if($p['insert'] || $p['view'] || $p['edit'] || $p['delete']){
130                 $table_permissions[$t][
'access'] = $table_permissions[$t][0] = true;
131             }
132         }
133
134         
return $table_permissions[$tn];
135     }
136
137     #########################################################
138
139     function get_sql_fields($table_name){
140         $sql_fields = array(
141             
'schools' => "`schools`.`id` as 'id', `schools`.`name` as 'name'",
142             
'departments' => "`departments`.`id` as 'id', `departments`.`name` as 'name', IF( CHAR_LENGTH(`schools1`.`name`), CONCAT_WS('', `schools1`.`name`), '') as 'school'",
143             
'class_time_table' => "`class_time_table`.`id` as 'id', `class_time_table`.`day` as 'day', TIME_FORMAT(`class_time_table`.`time_start`, '%r') as 'time_start', TIME_FORMAT(`class_time_table`.`time_end`, '%r') as 'time_end', `class_time_table`.`unit_code` as 'unit_code', `class_time_table`.`venue` as 'venue', IF( CHAR_LENGTH(`schools1`.`name`), CONCAT_WS('', `schools1`.`name`), '') as 'school', IF( CHAR_LENGTH(`departments1`.`name`), CONCAT_WS('', `departments1`.`name`), '') as 'department', `class_time_table`.`year_of_study` as 'year_of_study'",
144             
'exam_time_table' => "`exam_time_table`.`id` as 'id', if(`exam_time_table`.`date`,date_format(`exam_time_table`.`date`,'%m/%d/%Y'),'') as 'date', TIME_FORMAT(`exam_time_table`.`time_start`, '%r') as 'time_start', TIME_FORMAT(`exam_time_table`.`time_end`, '%r') as 'time_end', `exam_time_table`.`unit_code` as 'unit_code', `exam_time_table`.`venue` as 'venue', IF( CHAR_LENGTH(`schools1`.`name`), CONCAT_WS('', `schools1`.`name`), '') as 'school', IF( CHAR_LENGTH(`departments1`.`name`), CONCAT_WS('', `departments1`.`name`), '') as 'department', `exam_time_table`.`year_of_study` as 'year_of_study'",
145             
'personal_time_table' => "`personal_time_table`.`id` as 'id', `personal_time_table`.`day` as 'day', TIME_FORMAT(`personal_time_table`.`time_start`, '%r') as 'time_start', TIME_FORMAT(`personal_time_table`.`time_end`, '%r') as 'time_end', `personal_time_table`.`activity` as 'activity'",
146             
'student_details' => "`student_details`.`id` as 'id', `student_details`.`full_name` as 'full_name', IF( CHAR_LENGTH(`schools1`.`name`), CONCAT_WS('', `schools1`.`name`), '') as 'school', IF( CHAR_LENGTH(`departments1`.`name`), CONCAT_WS('', `departments1`.`name`), '') as 'department', `student_details`.`year_of_study` as 'year_of_study', `student_details`.`reg_no` as 'reg_no'",
147             
'notices' => "`notices`.`id` as 'id', `notices`.`notice` as 'notice', IF( CHAR_LENGTH(`schools1`.`name`), CONCAT_WS('', `schools1`.`name`), '') as 'school', IF( CHAR_LENGTH(`departments1`.`name`), CONCAT_WS('', `departments1`.`name`), '') as 'department', `notices`.`year_of_study` as 'year_of_study', if(`notices`.`date`,date_format(`notices`.`date`,'%m/%d/%Y'),'') as 'date'"
148         );
149
150         
if(isset($sql_fields[$table_name])){
151             
return $sql_fields[$table_name];
152         }
153
154         
return false;
155     }
156
157     #########################################################
158
159     function get_sql_from($table_name, $skip_permissions =
false){
160         $sql_from = array(
161             
'schools' => "`schools` ",
162             
'departments' => "`departments` LEFT JOIN `schools` as schools1 ON `schools1`.`id`=`departments`.`school` ",
163             
'class_time_table' => "`class_time_table` LEFT JOIN `schools` as schools1 ON `schools1`.`id`=`class_time_table`.`school` LEFT JOIN `departments` as departments1 ON `departments1`.`id`=`class_time_table`.`department` ",
164             
'exam_time_table' => "`exam_time_table` LEFT JOIN `schools` as schools1 ON `schools1`.`id`=`exam_time_table`.`school` LEFT JOIN `departments` as departments1 ON `departments1`.`id`=`exam_time_table`.`department` ",
165             
'personal_time_table' => "`personal_time_table` ",
166             
'student_details' => "`student_details` LEFT JOIN `schools` as schools1 ON `schools1`.`id`=`student_details`.`school` LEFT JOIN `departments` as departments1 ON `departments1`.`id`=`student_details`.`department` ",
167             
'notices' => "`notices` LEFT JOIN `schools` as schools1 ON `schools1`.`id`=`notices`.`school` LEFT JOIN `departments` as departments1 ON `departments1`.`id`=`notices`.`department` "
168         );
169
170         $pkey = array(
171             
'schools' => 'id',
172             
'departments' => 'id',
173             
'class_time_table' => 'id',
174             
'exam_time_table' => 'id',
175             
'personal_time_table' => 'id',
176             
'student_details' => 'id',
177             
'notices' => 'id'
178         );
179
180         
if(isset($sql_from[$table_name])){
181             
if($skip_permissions) return $sql_from[$table_name];
182
183             
// mm: build the query based on current member's permissions
184             $perm = getTablePermissions($table_name);
185             
if($perm[2] == 1){ // view owner only
186                 $sql_from[$table_name] .=
", membership_userrecords WHERE `{$table_name}`.`{$pkey[$table_name]}`=membership_userrecords.pkValue and membership_userrecords.tableName='{$table_name}' and lcase(membership_userrecords.memberID)='" . getLoggedMemberID() . "'";
187             }elseif($perm[
2] == 2){ // view group only
188                 $sql_from[$table_name] .=
", membership_userrecords WHERE `{$table_name}`.`{$pkey[$table_name]}`=membership_userrecords.pkValue and membership_userrecords.tableName='{$table_name}' and membership_userrecords.groupID='" . getLoggedGroupID() . "'";
189             }elseif($perm[
2] == 3){ // view all
190                 $sql_from[$table_name] .=
' WHERE 1=1';
191             }
else{ // view none
192                 
return false;
193             }
194             
return $sql_from[$table_name];
195         }
196
197         
return false;
198     }
199
200     #########################################################
201
202     function get_joined_record($table, $id, $skip_permissions =
false){
203         $sql_fields = get_sql_fields($table);
204         $sql_from = get_sql_from($table, $skip_permissions);
205
206         
if(!$sql_fields || !$sql_from) return false;
207
208         $pk = getPKFieldName($table);
209         
if(!$pk) return false;
210
211         $safe_id = makeSafe($id,
false);
212         $sql =
"SELECT {$sql_fields} FROM {$sql_from} AND `{$table}`.`{$pk}`='{$safe_id}'";
213         $eo[
'silentErrors'] = true;
214         $res = sql($sql, $eo);
215         
if($row = db_fetch_assoc($res)) return $row;
216
217         
return false;
218     }
219
220     #########################################################
221
222     function get_defaults($table){
223         
/* array of tables and their fields, with default values (or empty), excluding automatic values */
224         $defaults = array(
225             
'schools' => array(
226                 
'id' => '',
227                 
'name' => ''
228             ),
229             
'departments' => array(
230                 
'id' => '',
231                 
'name' => '',
232                 
'school' => ''
233             ),
234             
'class_time_table' => array(
235                 
'id' => '',
236                 
'day' => '',
237                 
'time_start' => '',
238                 
'time_end' => '',
239                 
'unit_code' => '',
240                 
'venue' => '',
241                 
'school' => '',
242                 
'department' => '',
243                 
'year_of_study' => ''
244             ),
245             
'exam_time_table' => array(
246                 
'id' => '',
247                 
'date' => '1',
248                 
'time_start' => '',
249                 
'time_end' => '',
250                 
'unit_code' => '',
251                 
'venue' => '',
252                 
'school' => '',
253                 
'department' => '',
254                 
'year_of_study' => ''
255             ),
256             
'personal_time_table' => array(
257                 
'id' => '',
258                 
'day' => '',
259                 
'time_start' => '',
260                 
'time_end' => '',
261                 
'activity' => ''
262             ),
263             
'student_details' => array(
264                 
'id' => '',
265                 
'full_name' => '',
266                 
'school' => '',
267                 
'department' => '',
268                 
'year_of_study' => '',
269                 
'reg_no' => ''
270             ),
271             
'notices' => array(
272                 
'id' => '',
273                 
'notice' => '',
274                 
'school' => '',
275                 
'department' => '',
276                 
'year_of_study' => '',
277                 
'date' => ''
278             )
279         );
280
281         
return isset($defaults[$table]) ? $defaults[$table] : array();
282     }
283
284     #########################################################
285
286     function logInMember(){
287         $redir =
'index.php';
288         
if($_POST['signIn'] != ''){
289             
if($_POST['username'] != '' && $_POST['password'] != ''){
290                 $username = makeSafe(strtolower($_POST[
'username']));
291                 $password = md5($_POST[
'password']);
292
293                 
if(sqlValue("select count(1) from membership_users where lcase(memberID)='$username' and passMD5='$password' and isApproved=1 and isBanned=0")==1){
294                     $_SESSION[
'memberID']=$username;
295                     $_SESSION[
'memberGroupID']=sqlValue("select groupID from membership_users where lcase(memberID)='$username'");
296                     
if($_POST['rememberMe']==1){
297                         @setcookie(
'Jisort_rememberMe', md5($username.$password), time()+86400*30);
298                     }
else{
299                         @setcookie(
'Jisort_rememberMe', '', time()-86400*30);
300                     }
301
302                     
// hook: login_ok
303                     
if(function_exists('login_ok')){
304                         $args=array();
305                         
if(!$redir=login_ok(getMemberInfo(), $args)){
306                             $redir=
'index.php';
307                         }
308                     }
309
310                     redirect($redir);
311                     exit;
312                 }
313             }
314
315             
// hook: login_failed
316             
if(function_exists('login_failed')){
317                 $args=array();
318                 login_failed(array(
319                     
'username' => $_POST['username'],
320                     
'password' => $_POST['password'],
321                     
'IP' => $_SERVER['REMOTE_ADDR']
322                     ), $args);
323             }
324
325             
if(!headers_sent()) header('HTTP/1.0 403 Forbidden');
326             redirect(
"index.php?loginFailed=1");
327             exit;
328         }elseif((!$_SESSION[
'memberID'] || $_SESSION['memberID']==$adminConfig['anonymousMember']) && $_COOKIE['Jisort_rememberMe']!=''){
329             $chk=makeSafe($_COOKIE[
'Jisort_rememberMe']);
330             
if($username=sqlValue("select memberID from membership_users where convert(md5(concat(memberID, passMD5)), char)='$chk' and isBanned=0")){
331                 $_SESSION[
'memberID']=$username;
332                 $_SESSION[
'memberGroupID']=sqlValue("select groupID from membership_users where lcase(memberID)='$username'");
333             }
334         }
335     }
336
337     #########################################################
338
339     function htmlUserBar(){
340         
global $adminConfig, $Translation;
341         
if(!defined('PREPEND_PATH')) define('PREPEND_PATH', '');
342
343         ob_start();
344         $home_page = (basename($_SERVER[
'PHP_SELF'])=='index.php' ? true : false);
345
346         ?>
347         <!-- <nav
class="navbar navbar-default navbar-fixed-top hidden-print" role="navigation"> -->
348         <nav
class="navbar navbar-expand-lg navbar-dark bg-dark fixed-top" role="navigation">
349             <!-- application title
is obtained from the name besides the yellow database icon in AppGini, use underscores for spaces -->
350             <a
class="navbar-brand" href="<?php echo PREPEND_PATH; ?>index.php"><i class="glyphicon glyphicon-home"></i> Hệ thống xếp lịch học tín chỉ cho sinh viên CNTT</a>
351             <button type=
"button" class="navbar-toggle" data-toggle="collapse" data-target=".navbar-collapse">
352                 <span
class="sr-only">Toggle navigation</span>
353                 <span
class="icon-bar"></span>
354                 <span
class="icon-bar"></span>
355                 <span
class="icon-bar"></span>
356             </button>
357             <div
class="collapse navbar-collapse" id="navbarResponsive">
358                 <ul
class="navbar-nav navbar-sidenav codefly" id="exampleAccordion">
359                     <?php
if(!$home_page){ ?>
360                         <?php echo NavMenus(); ?>
361                     <?php } ?>
362                 </ul>
363
364                 <?php
if(getLoggedAdmin()){ ?>
365                     <ul
class="nav navbar-nav">
366                         <a href=
"<?php echo PREPEND_PATH; ?>admin/pageHome.php" class="btn btn-danger navbar-btn hidden-xs" title="<?php echo html_attr($Translation['admin area']); ?>"><i class="glyphicon glyphicon-cog"></i> <?php echo $Translation['admin area']; ?></a>
367                         <a href=
"<?php echo PREPEND_PATH; ?>admin/pageHome.php" class="btn btn-danger navbar-btn visible-xs btn-lg" title="<?php echo html_attr($Translation['admin area']); ?>"><i class="glyphicon glyphicon-cog"></i> <?php echo $Translation['admin area']; ?></a>
368                     </ul>
369                 <?php } ?>
370
371                 <?php
if(!$_GET['signIn'] && !$_GET['loginFailed']){ ?>
372                     <?php
if(getLoggedMemberID() == $adminConfig['anonymousMember']){ ?>
373                         <p
class="navbar-text navbar-right">&nbsp;</p>
374                         <a href=
"<?php echo PREPEND_PATH; ?>index.php?signIn=1" class="btn btn-success navbar-btn navbar-right"><?php echo $Translation['sign in']; ?></a>
375                         <p
class="navbar-text navbar-right">
376                             <?php echo $Translation[
'not signed in']; ?>
377                         </p>
378                     <?php }
else{ ?>
379                         <ul
class="nav navbar-nav navbar-right hidden-xs" style="min-width: 330px;">
380                             <a
class="btn navbar-btn btn-default" href="<?php echo PREPEND_PATH; ?>index.php?signOut=1"><i class="glyphicon glyphicon-log-out"></i> <?php echo $Translation['sign out']; ?></a>
381                             <p
class="navbar-text">
382                                 <?php echo $Translation[
'signed as']; ?> <strong><a href="<?php echo PREPEND_PATH; ?>membership_profile.php" class="navbar-link"><?php echo getLoggedMemberID(); ?></a></strong>
383                             </p>
384                         </ul>
385                         <ul
class="nav navbar-nav visible-xs">
386                             <a
class="btn navbar-btn btn-default btn-lg visible-xs" href="<?php echo PREPEND_PATH; ?>index.php?signOut=1"><i class="glyphicon glyphicon-log-out"></i> <?php echo $Translation['sign out']; ?></a>
387                             <p
class="navbar-text text-center">
388                                 <?php echo $Translation[
'signed as']; ?> <strong><a href="<?php echo PREPEND_PATH; ?>membership_profile.php" class="navbar-link"><?php echo getLoggedMemberID(); ?></a></strong>
389                             </p>
390                         </ul>
391                         <script>
392                             
/* periodically check if user is still signed in */
393                             setInterval(function(){
394                                 $j.ajax({
395                                     url:
'<?php echo PREPEND_PATH; ?>ajax_check_login.php',
396                                     success: function(username){
397                                         
if(!username.length) window.location = '<?php echo PREPEND_PATH; ?>index.php?signIn=1';
398                                     }
399                                 });
400                             },
60000);
401                         </script>
402                     <?php } ?>
403                 <?php } ?>
404             </div>
405         </nav>
406         <?php
407
408         $html = ob_get_contents();
409         ob_end_clean();
410
411         
return $html;
412     }
413
414     #########################################################
415
416     function showNotifications($msg =
'', $class = '', $fadeout = true){
417         
global $Translation;
418
419         $notify_template_no_fadeout =
'<div id="%%ID%%" class="alert alert-dismissable %%CLASS%%" style="display: none; padding-top: 6px; padding-bottom: 6px;">' .
420                     
'<button type="button" class="close" data-dismiss="alert" aria-hidden="true">&times;</button>' .
421                     
'%%MSG%%</div>' .
422                     
'<script> jQuery(function(){ /* */ jQuery("#%%ID%%").show("slow"); }); </script>'."\n";
423         $notify_template =
'<div id="%%ID%%" class="alert %%CLASS%%" style="display: none; padding-top: 6px; padding-bottom: 6px;">%%MSG%%</div>' .
424                     
'<script>' .
425                         
'jQuery(function(){' .
426                             
'jQuery("#%%ID%%").show("slow", function(){' .
427                                 
'setTimeout(function(){ /* */ jQuery("#%%ID%%").hide("slow"); }, 4000);' .
428                             
'});' .
429                         
'});' .
430                     
'</script>'."\n";
431
432         
if(!$msg){ // if no msg, use url to detect message to display
433             
if($_REQUEST['record-added-ok'] != ''){
434                 $msg = $Translation[
'new record saved'];
435                 $
class = 'alert-success';
436             }elseif($_REQUEST[
'record-added-error'] != ''){
437                 $msg = $_SESSION[
'custom_alert'];
438                 unset($_SESSION[
'custom_alert']);
439                 $
class = 'alert-danger';
440                 $fadeout =
false;
441             }elseif($_REQUEST[
'record-updated-ok'] != ''){
442                 $msg = $Translation[
'record updated'];
443                 $
class = 'alert-success';
444             }elseif($_REQUEST[
'record-updated-error'] != ''){
445                 $msg = $Translation[
'Couldn\'t save changes to the record'];
446                 $
class = 'alert-danger';
447                 $fadeout =
false;
448             }elseif($_REQUEST[
'record-deleted-ok'] != ''){
449                 $msg = $Translation[
'The record has been deleted successfully'];
450                 $
class = 'alert-success';
451                 $fadeout =
false;
452             }elseif($_REQUEST[
'record-deleted-error'] != ''){
453                 $msg = $Translation[
'Couldn\'t delete this record'];
454                 $
class = 'alert-danger';
455                 $fadeout =
false;
456             }
else{
457                 
return '';
458             }
459         }
460         $id =
'notification-' . rand();
461
462         $
out = ($fadeout ? $notify_template : $notify_template_no_fadeout);
463         $
out = str_replace('%%ID%%', $id, $out);
464         $
out = str_replace('%%MSG%%', $msg, $out);
465         $
out = str_replace('%%CLASS%%', $class, $out);
466
467         
return $out;
468     }
469
470     #########################################################
471
472     function parseMySQLDate($date, $altDate){
473         
// is $date valid?
474         
if(preg_match("/^\d{4}-\d{1,2}-\d{1,2}$/", trim($date))){
475             
return trim($date);
476         }
477
478         
if($date != '--' && preg_match("/^\d{4}-\d{1,2}-\d{1,2}$/", trim($altDate))){
479             
return trim($altDate);
480         }
481
482         
if($date != '--' && $altDate && intval($altDate)==$altDate){
483             
return @date('Y-m-d', @time() + ($altDate >= 1 ? $altDate - 1 : $altDate) * 86400);
484         }
485
486         
return '';
487     }
488
489     #########################################################
490
491     function parseCode($code, $isInsert=
true, $rawData=false){
492         
if($isInsert){
493             $arrCodes=array(
494                 
'<%%creatorusername%%>' => $_SESSION['memberID'],
495                 
'<%%creatorgroupid%%>' => $_SESSION['memberGroupID'],
496                 
'<%%creatorip%%>' => $_SERVER['REMOTE_ADDR'],
497                 
'<%%creatorgroup%%>' => sqlValue("select name from membership_groups where groupID='{$_SESSION['memberGroupID']}'"),
498
499                 
'<%%creationdate%%>' => ($rawData ? @date('Y-m-d') : @date('n/j/Y')),
500                 
'<%%creationtime%%>' => ($rawData ? @date('H:i:s') : @date('h:i:s a')),
501                 
'<%%creationdatetime%%>' => ($rawData ? @date('Y-m-d H:i:s') : @date('n/j/Y h:i:s a')),
502                 
'<%%creationtimestamp%%>' => ($rawData ? @date('Y-m-d H:i:s') : @time())
503             );
504         }
else{
505             $arrCodes=array(
506                 
'<%%editorusername%%>' => $_SESSION['memberID'],
507                 
'<%%editorgroupid%%>' => $_SESSION['memberGroupID'],
508                 
'<%%editorip%%>' => $_SERVER['REMOTE_ADDR'],
509                 
'<%%editorgroup%%>' => sqlValue("select name from membership_groups where groupID='{$_SESSION['memberGroupID']}'"),
510
511                 
'<%%editingdate%%>' => ($rawData ? @date('Y-m-d') : @date('n/j/Y')),
512                 
'<%%editingtime%%>' => ($rawData ? @date('H:i:s') : @date('h:i:s a')),
513                 
'<%%editingdatetime%%>' => ($rawData ? @date('Y-m-d H:i:s') : @date('n/j/Y h:i:s a')),
514                 
'<%%editingtimestamp%%>' => ($rawData ? @date('Y-m-d H:i:s') : @time())
515             );
516         }
517
518         $pc=str_ireplace(array_keys($arrCodes), array_values($arrCodes), $code);
519
520         
return $pc;
521     }
522
523     #########################################################
524
525     function addFilter($index, $filterAnd, $filterField, $filterOperator, $filterValue){
526         
// validate input
527         
if($index < 1 || $index > 80 || !is_int($index)) return false;
528         
if($filterAnd != 'or') $filterAnd = 'and';
529         $filterField = intval($filterField);
530
531         
/* backward compatibility */
532         
if(in_array($filterOperator, $GLOBALS['filter_operators'])){
533             $filterOperator = array_search($filterOperator, $GLOBALS[
'filter_operators']);
534         }
535
536         
if(!in_array($filterOperator, array_keys($GLOBALS['filter_operators']))){
537             $filterOperator =
'like';
538         }
539
540         
if(!$filterField){
541             $filterOperator =
'';
542             $filterValue =
'';
543         }
544
545         $_REQUEST[
'FilterAnd'][$index] = $filterAnd;
546         $_REQUEST[
'FilterField'][$index] = $filterField;
547         $_REQUEST[
'FilterOperator'][$index] = $filterOperator;
548         $_REQUEST[
'FilterValue'][$index] = $filterValue;
549
550         
return true;
551     }
552
553     #########################################################
554
555     function clearFilters(){
556         
for($i=1; $i<=80; $i++){
557             addFilter($i,
'', 0, '', '');
558         }
559     }
560
561     #########################################################
562
563     
if(!function_exists('str_ireplace')){
564         function str_ireplace($search, $replace, $subject){
565             $ret=$subject;
566             
if(is_array($search)){
567                 
for($i=0; $i<count($search); $i++){
568                     $ret=str_ireplace($search[$i], $replace[$i], $ret);
569                 }
570             }
else{
571                 $ret=preg_replace(
'/'.preg_quote($search, '/').'/i', $replace, $ret);
572             }
573
574             
return $ret;
575         }
576     }
577
578     #########################################################
579
580     
/**
581     * Loads a given view
from the templates folder, passing the given data to it
582     * @param $view the name of a php file (without extension) to be loaded
from the 'templates' folder
583     * @param $the_data_to_pass_to_the_view (optional) associative array containing the data to pass to the view
584     * @
return the output of the parsed view as a string
585     */

586     function loadView($view, $the_data_to_pass_to_the_view=
false){
587         
global $Translation;
588
589         $view = dirname(__FILE__).
"/templates/$view.php";
590         
if(!is_file($view)) return false;
591
592         
if(is_array($the_data_to_pass_to_the_view)){
593             
foreach($the_data_to_pass_to_the_view as $k => $v)
594                 $$k = $v;
595         }
596         unset($the_data_to_pass_to_the_view, $k, $v);
597
598         ob_start();
599         @include($view);
600         $
out=ob_get_contents();
601         ob_end_clean();
602
603         
return $out;
604     }
605
606     #########################################################
607
608     
/**
609     * Loads a table template
from the templates folder, passing the given data to it
610     * @param $table_name the name of the table whose template
is to be loaded from the 'templates' folder
611     * @param $the_data_to_pass_to_the_table associative array containing the data to pass to the table template
612     * @
return the output of the parsed table template as a string
613     */

614     function loadTable($table_name, $the_data_to_pass_to_the_table = array()){
615         $dont_load_header = $the_data_to_pass_to_the_table[
'dont_load_header'];
616         $dont_load_footer = $the_data_to_pass_to_the_table[
'dont_load_footer'];
617
618         $header = $table = $footer =
'';
619
620         
if(!$dont_load_header){
621             
// try to load tablename-header
622             
if(!($header = loadView("{$table_name}-header", $the_data_to_pass_to_the_table))){
623                 $header = loadView(
'table-common-header', $the_data_to_pass_to_the_table);
624             }
625         }
626
627         $table = loadView($table_name, $the_data_to_pass_to_the_table);
628
629         
if(!$dont_load_footer){
630             
// try to load tablename-footer
631             
if(!($footer = loadView("{$table_name}-footer", $the_data_to_pass_to_the_table))){
632                 $footer = loadView(
'table-common-footer', $the_data_to_pass_to_the_table);
633             }
634         }
635
636         
return "{$header}{$table}{$footer}";
637     }
638
639     #########################################################
640
641     function filterDropdownBy($filterable, $filterers, $parentFilterers, $parentPKField, $parentCaption, $parentTable, &$filterableCombo){
642         $filterersArray = explode(
',', $filterers);
643         $parentFilterersArray = explode(
',', $parentFilterers);
644         $parentFiltererList =
'`' . implode('`, `', $parentFilterersArray) . '`';
645         $res=sql(
"SELECT `$parentPKField`, $parentCaption, $parentFiltererList FROM `$parentTable` ORDER BY 2", $eo);
646         $filterableData = array();
647         
while($row=db_fetch_row($res)){
648             $filterableData[$row[
0]] = $row[1];
649             $filtererIndex =
0;
650             
foreach($filterersArray as $filterer){
651                 $filterableDataByFilterer[$filterer][$row[$filtererIndex +
2]][$row[0]] = $row[1];
652                 $filtererIndex++;
653             }
654             $row[
0] = addslashes($row[0]);
655             $row[
1] = addslashes($row[1]);
656             $jsonFilterableData .=
"\"{$row[0]}\":\"{$row[1]}\",";
657         }
658         $jsonFilterableData .=
'}';
659         $jsonFilterableData =
'{'.str_replace(',}', '}', $jsonFilterableData);
660         $filterJS =
"\nvar {$filterable}_data = $jsonFilterableData;";
661
662         
foreach($filterersArray as $filterer){
663             
if(is_array($filterableDataByFilterer[$filterer])) foreach($filterableDataByFilterer[$filterer] as $filtererItem => $filterableItem){
664                 $jsonFilterableDataByFilterer[$filterer] .=
'"'.addslashes($filtererItem).'":{';
665                 
foreach($filterableItem as $filterableItemID => $filterableItemData){
666                     $jsonFilterableDataByFilterer[$filterer] .=
'"'.addslashes($filterableItemID).'":"'.addslashes($filterableItemData).'",';
667                 }
668                 $jsonFilterableDataByFilterer[$filterer] .=
'},';
669             }
670             $jsonFilterableDataByFilterer[$filterer] .=
'}';
671             $jsonFilterableDataByFilterer[$filterer] =
'{'.str_replace(',}', '}', $jsonFilterableDataByFilterer[$filterer]);
672
673             $filterJS.=
"\n\n// code for filtering {$filterable} by {$filterer}\n";
674             $filterJS.=
"\nvar {$filterable}_data_by_{$filterer} = {$jsonFilterableDataByFilterer[$filterer]}; ";
675             $filterJS.=
"\nvar selected_{$filterable} = \$j('#{$filterable}').val();";
676             $filterJS.=
"\nvar {$filterable}_change_by_{$filterer} = function(){";
677             $filterJS.=
"\n\t$('{$filterable}').options.length=0;";
678             $filterJS.=
"\n\t$('{$filterable}').options[0] = new Option();";
679             $filterJS.=
"\n\tif(\$j('#{$filterer}').val()){";
680             $filterJS.=
"\n\t\tfor({$filterable}_item in {$filterable}_data_by_{$filterer}[\$j('#{$filterer}').val()]){";
681             $filterJS.=
"\n\t\t\t$('{$filterable}').options[$('{$filterable}').options.length] = new Option(";
682             $filterJS.=
"\n\t\t\t\t{$filterable}_data_by_{$filterer}[\$j('#{$filterer}').val()][{$filterable}_item],";
683             $filterJS.=
"\n\t\t\t\t{$filterable}_item,";
684             $filterJS.=
"\n\t\t\t\t({$filterable}_item == selected_{$filterable} ? true : false),";
685             $filterJS.=
"\n\t\t\t\t({$filterable}_item == selected_{$filterable} ? true : false)";
686             $filterJS.=
"\n\t\t\t);";
687             $filterJS.=
"\n\t\t}";
688             $filterJS.=
"\n\t}else{";
689             $filterJS.=
"\n\t\tfor({$filterable}_item in {$filterable}_data){";
690             $filterJS.=
"\n\t\t\t$('{$filterable}').options[$('{$filterable}').options.length] = new Option(";
691             $filterJS.=
"\n\t\t\t\t{$filterable}_data[{$filterable}_item],";
692             $filterJS.=
"\n\t\t\t\t{$filterable}_item,";
693             $filterJS.=
"\n\t\t\t\t({$filterable}_item == selected_{$filterable} ? true : false),";
694             $filterJS.=
"\n\t\t\t\t({$filterable}_item == selected_{$filterable} ? true : false)";
695             $filterJS.=
"\n\t\t\t);";
696             $filterJS.=
"\n\t\t}";
697             $filterJS.=
"\n\t\tif(selected_{$filterable} && selected_{$filterable} == \$j('#{$filterable}').val()){";
698             $filterJS.=
"\n\t\t\tfor({$filterer}_item in {$filterable}_data_by_{$filterer}){";
699             $filterJS.=
"\n\t\t\t\tfor({$filterable}_item in {$filterable}_data_by_{$filterer}[{$filterer}_item]){";
700             $filterJS.=
"\n\t\t\t\t\tif({$filterable}_item == selected_{$filterable}){";
701             $filterJS.=
"\n\t\t\t\t\t\t$('{$filterer}').value = {$filterer}_item;";
702             $filterJS.=
"\n\t\t\t\t\t\tbreak;";
703             $filterJS.=
"\n\t\t\t\t\t}";
704             $filterJS.=
"\n\t\t\t\t}";
705             $filterJS.=
"\n\t\t\t\tif({$filterable}_item == selected_{$filterable}) break;";
706             $filterJS.=
"\n\t\t\t}";
707             $filterJS.=
"\n\t\t}";
708             $filterJS.=
"\n\t}";
709             $filterJS.=
"\n\t$('{$filterable}').highlight();";
710             $filterJS.=
"\n};";
711             $filterJS.=
"\n$('{$filterer}').observe('change', function(){ /* */ window.setTimeout({$filterable}_change_by_{$filterer}, 25); });";
712             $filterJS.=
"\n";
713         }
714
715         $filterableCombo =
new Combo;
716         $filterableCombo->ListType =
0;
717         $filterableCombo->ListItem = array_slice(array_values($filterableData),
0, 10);
718         $filterableCombo->ListData = array_slice(array_keys($filterableData),
0, 10);
719         $filterableCombo->SelectName = $filterable;
720         $filterableCombo->AllowNull =
true;
721
722         
return $filterJS;
723     }
724
725     #########################################################
726     function br2nl($text){
727         
return preg_replace('/\<br(\s*)?\/?\>/i', "\n", $text);
728     }
729
730     #########################################################
731
732     
if(!function_exists('htmlspecialchars_decode')){
733         function htmlspecialchars_decode($
string, $quote_style = ENT_COMPAT){
734             
return strtr($string, array_flip(get_html_translation_table(HTML_SPECIALCHARS, $quote_style)));
735         }
736     }
737
738     #########################################################
739
740     function entitiesToUTF8($input){
741         
return preg_replace_callback('/(&#[0-9]+;)/', '_toUTF8', $input);
742     }
743
744     function _toUTF8($m){
745         
if(function_exists('mb_convert_encoding')){
746             
return mb_convert_encoding($m[1], "UTF-8", "HTML-ENTITIES");
747         }
else{
748             
return $m[1];
749         }
750     }
751
752     #########################################################
753
754     function func_get_args_byref() {
755         
if(!function_exists('debug_backtrace')) return false;
756
757         $trace = debug_backtrace();
758         
return $trace[1]['args'];
759     }
760
761     #########################################################
762
763     function permissions_sql($table, $level =
'all'){
764         
if(!in_array($level, array('user', 'group'))){ $level = 'all'; }
765         $perm = getTablePermissions($table);
766         $
from = '';
767         $
where = '';
768         $pk = getPKFieldName($table);
769
770         
if($perm[2] == 1 || ($perm[2] > 1 && $level == 'user')){ // view owner only
771             $
from = 'membership_userrecords';
772             $
where = "(`$table`.`$pk`=membership_userrecords.pkValue and membership_userrecords.tableName='$table' and lcase(membership_userrecords.memberID)='".getLoggedMemberID()."')";
773         }elseif($perm[
2] == 2 || ($perm[2] > 2 && $level == 'group')){ // view group only
774             $
from = 'membership_userrecords';
775             $
where = "(`$table`.`$pk`=membership_userrecords.pkValue and membership_userrecords.tableName='$table' and membership_userrecords.groupID='".getLoggedGroupID()."')";
776         }elseif($perm[
2] == 3){ // view all
777             
// no further action
778         }elseif($perm[
2] == 0){ // view none
779             
return false;
780         }
781
782         
return array('where' => $where, 'from' => $from, 0 => $where, 1 => $from);
783     }
784
785     #########################################################
786
787     function error_message($msg, $back_url =
'', $full_page = true){
788         $curr_dir = dirname(__FILE__);
789         
global $Translation;
790
791         ob_start();
792
793         
if($full_page) include_once($curr_dir . '/header.php');
794
795         echo
'<div class="panel panel-danger">';
796             echo
'<div class="panel-heading"><h3 class="panel-title">' . $Translation['error:'] . '</h3></div>';
797             echo
'<div class="panel-body"><p class="text-danger">' . $msg . '</p>';
798             
if($back_url !== false){ // explicitly passing false suppresses the back link completely
799                 echo
'<div class="text-center">';
800                 
if($back_url){
801                     echo
'<a href="' . $back_url . '" class="btn btn-danger btn-lg vspacer-lg"><i class="glyphicon glyphicon-chevron-left"></i> ' . $Translation['< back'] . '</a>';
802                 }
else{
803                     echo
'<a href="#" class="btn btn-danger btn-lg vspacer-lg" onclick="history.go(-1); return false;"><i class="glyphicon glyphicon-chevron-left"></i> ' . $Translation['< back'] . '</a>';
804                 }
805                 echo
'</div>';
806             }
807             echo
'</div>';
808         echo
'</div>';
809
810         
if($full_page) include_once($curr_dir . '/footer.php');
811
812         $
out = ob_get_contents();
813         ob_end_clean();
814
815         
return $out;
816     }
817
818     #########################################################
819
820     function toMySQLDate($formattedDate, $sep = datalist_date_separator, $ord = datalist_date_format){
821         
// extract date elements
822         $de=explode($sep, $formattedDate);
823         $mySQLDate=intval($de[strpos($ord,
'Y')]).'-'.intval($de[strpos($ord, 'm')]).'-'.intval($de[strpos($ord, 'd')]);
824         
return $mySQLDate;
825     }
826
827     #########################################################
828
829     function reIndex(&$arr){
830         $i=
1;
831         
foreach($arr as $n=>$v){
832             $arr2[$i]=$n;
833             $i++;
834         }
835         
return $arr2;
836     }
837
838     #########################################################
839
840     function get_embed($provider, $url, $max_width =
'', $max_height = '', $retrieve = 'html'){
841         
global $Translation;
842         
if(!$url) return '';
843
844         $providers = array(
845             
'youtube' => array('oembed' => 'http://www.youtube.com/oembed?'),
846             
'googlemap' => array('oembed' => '', 'regex' => '/^http.*\.google\..*maps/i')
847         );
848
849         
if(!isset($providers[$provider])){
850             
return '<div class="text-danger">' . $Translation['invalid provider'] . '</div>';
851         }
852
853         
if(isset($providers[$provider]['regex']) && !preg_match($providers[$provider]['regex'], $url)){
854             
return '<div class="text-danger">' . $Translation['invalid url'] . '</div>';
855         }
856
857         
if($providers[$provider]['oembed']){
858             $oembed = $providers[$provider][
'oembed'] . 'url=' . urlencode($url) . "&maxwidth={$max_width}&maxheight={$max_height}&format=json";
859             $data_json = request_cache($oembed);
860
861             $data = json_decode($data_json,
true);
862             
if($data === null){
863                 
/* an error was returned rather than a json string */
864                 
if($retrieve == 'html') return "<div class=\"text-danger\">{$data_json}\n<!-- {$oembed} --></div>";
865                 
return '';
866             }
867
868             
return (isset($data[$retrieve]) ? $data[$retrieve] : $data['html']);
869         }
870
871         
/* special cases (where there is no oEmbed provider) */
872         
if($provider == 'googlemap') return get_embed_googlemap($url, $max_width, $max_height, $retrieve);
873
874         
return '<div class="text-danger">Invalid provider!</div>';
875     }
876
877     #########################################################
878
879     function get_embed_googlemap($url, $max_width =
'', $max_height = '', $retrieve = 'html'){
880         
global $Translation;
881         $url_parts = parse_url($url);
882         $coords_regex =
'/-?\d+(\.\d+)?[,+]-?\d+(\.\d+)?(,\d{1,2}z)?/'; /* https://stackoverflow.com/questions/2660201 */
883
884         
if(preg_match($coords_regex, $url_parts['path'] . '?' . $url_parts['query'], $m)){
885             list($lat, $
long, $zoom) = explode(',', $m[0]);
886             $zoom = intval($zoom);
887             
if(!$zoom) $zoom = 10; /* default zoom */
888             
if(!$max_height) $max_height = 360;
889             
if(!$max_width) $max_width = 480;
890
891             $api_key =
'';
892             $embed_url =
"https://www.google.com/maps/embed/v1/view?key={$api_key}&center={$lat},{$long}&zoom={$zoom}&maptype=roadmap";
893             $thumbnail_url =
"https://maps.googleapis.com/maps/api/staticmap?key={$api_key}&center={$lat},{$long}&zoom={$zoom}&maptype=roadmap&size={$max_width}x{$max_height}";
894
895             
if($retrieve == 'html'){
896                 
return "<iframe width=\"{$max_width}\" height=\"{$max_height}\" frameborder=\"0\" style=\"border:0\" src=\"{$embed_url}\"></iframe>";
897             }
else{
898                 
return $thumbnail_url;
899             }
900         }
else{
901             
return '<div class="text-danger">' . $Translation['cant retrieve coordinates from url'] . '</div>';
902         }
903     }
904
905     #########################################################
906
907     function request_cache($request, $force_fetch =
false){
908         $max_cache_lifetime =
7 * 86400; /* max cache lifetime in seconds before refreshing from source */
909
910         
/* membership_cache table exists? if not, create it */
911         
static $cache_table_exists = false;
912         
if(!$cache_table_exists && !$force_fetch){
913             $te = sqlValue(
"show tables like 'membership_cache'");
914             
if(!$te){
915                 
if(!sql("CREATE TABLE `membership_cache` (`request` VARCHAR(100) NOT NULL, `request_ts` INT, `response` TEXT NOT NULL, PRIMARY KEY (`request`))", $eo)){
916                     
/* table can't be created, so force fetching request */
917                     
return request_cache($request, true);
918                 }
919             }
920             $cache_table_exists =
true;
921         }
922
923         
/* retrieve response from cache if exists */
924         
if(!$force_fetch){
925             $res = sql(
"select response, request_ts from membership_cache where request='" . md5($request) . "'", $eo);
926             
if(!$row = db_fetch_array($res)) return request_cache($request, true);
927
928             $response = $row[
0];
929             $response_ts = $row[
1];
930             
if($response_ts < time() - $max_cache_lifetime) return request_cache($request, true);
931         }
932
933         
/* if no response in cache, issue a request */
934         
if(!$response || $force_fetch){
935             $response = @file_get_contents($request);
936             
if($response === false){
937                 $error = error_get_last();
938                 $error_message = preg_replace(
'/.*: (.*)/', '$1', $error['message']);
939                 
return $error_message;
940             }elseif($cache_table_exists){
941                 
/* store response in cache */
942                 $ts = time();
943                 sql(
"replace into membership_cache set request='" . md5($request) . "', request_ts='{$ts}', response='" . makeSafe($response, false) . "'", $eo);
944             }
945         }
946
947         
return $response;
948     }
949
950     #########################################################
951
952     function check_record_permission($table, $id, $perm =
'view'){
953         
if($perm != 'edit' && $perm != 'delete') $perm = 'view';
954
955         $perms = getTablePermissions($table);
956         
if(!$perms[$perm]) return false;
957
958         $safe_id = makeSafe($id);
959         $safe_table = makeSafe($table);
960
961         
if($perms[$perm] == 1){ // own records only
962             $username = getLoggedMemberID();
963             $owner = sqlValue(
"select memberID from membership_userrecords where tableName='{$safe_table}' and pkValue='{$safe_id}'");
964             
if($owner == $username) return true;
965         }elseif($perms[$perm] ==
2){ // group records
966             $group_id = getLoggedGroupID();
967             $owner_group_id = sqlValue(
"select groupID from membership_userrecords where tableName='{$safe_table}' and pkValue='{$safe_id}'");
968             
if($owner_group_id == $group_id) return true;
969         }elseif($perms[$perm] ==
3){ // all records
970             
return true;
971         }
972
973         
return false;
974     }
975
976     #########################################################
977
978     function NavMenus($options = array()){
979         
if(!defined('PREPEND_PATH')) define('PREPEND_PATH', '');
980         
global $Translation;
981         $prepend_path = PREPEND_PATH;
982
983         
/* default options */
984         
if(empty($options)){
985             $options = array(
986                 
'tabs' => 7
987             );
988         }
989
990         $table_group_name = array_keys(get_table_groups());
/* 0 => group1, 1 => group2 .. */
991         
/* if only one group named 'None', set to translation of 'select a table' */
992         
if((count($table_group_name) == 1 && $table_group_name[0] == 'None') || count($table_group_name) < 1) $table_group_name[0] = $Translation['select a table'];
993         $table_group_index = array_flip($table_group_name);
/* group1 => 0, group2 => 1 .. */
994         $menu = array_fill(
0, count($table_group_name), '');
995
996         $t = time();
997         $arrTables = getTableList();
998         
if(is_array($arrTables)){
999             
foreach($arrTables as $tn => $tc){
1000                 
/* ---- list of tables where hide link in nav menu is set ---- */
1001                 $tChkHL = array_search($tn, array());
1002
1003                 
/* ---- list of tables where filter first is set ---- */
1004                 $tChkFF = array_search($tn, array());
1005                 
if($tChkFF !== false && $tChkFF !== null){
1006                     $searchFirst =
'&Filter_x=1';
1007                 }
else{
1008                     $searchFirst =
'';
1009                 }
1010
1011                 
/* when no groups defined, $table_group_index['None'] is NULL, so $menu_index is still set to 0 */
1012                 $menu_index = intval($table_group_index[$tc[
3]]);
1013                 
if(!$tChkHL && $tChkHL !== 0) $menu[$menu_index] .= "<li class=\"nav-item\"><a href=\"{$prepend_path}{$tn}_view.php?t={$t}{$searchFirst}\"><img src=\"{$prepend_path}" . ($tc[2] ? $tc[2] : 'blank.gif') . "\" height=\"32\"> {$tc[0]}</a></li>";
1014             }
1015         }
1016
1017         
// custom nav links, as defined in "hooks/links-navmenu.php"
1018         
global $navLinks;
1019         
if(is_array($navLinks)){
1020             $memberInfo = getMemberInfo();
1021             $links_added = array();
1022             
foreach($navLinks as $link){
1023                 
if(!isset($link['url']) || !isset($link['title'])) continue;
1024                 
if($memberInfo['admin'] || @in_array($memberInfo['group'], $link['groups']) || @in_array('*', $link['groups'])){
1025                     $menu_index = intval($link[
'table_group']);
1026                     
if(!$links_added[$menu_index]) $menu[$menu_index] .= '<li class="divider"></li>';
1027
1028                     
/* add prepend_path to custom links if they aren't absolute links */
1029                     
if(!preg_match('/^(http|\/\/)/i', $link['url'])) $link['url'] = $prepend_path . $link['url'];
1030                     
if(!preg_match('/^(http|\/\/)/i', $link['icon']) && $link['icon']) $link['icon'] = $prepend_path . $link['icon'];
1031
1032                     $menu[$menu_index] .=
"<li class=\"nav-item\"><a href=\"{$link['url']}\"><img src=\"" . ($link['icon'] ? $link['icon'] : "{$prepend_path}blank.gif") . "\" height=\"32\"> {$link['title']}</a></li>";
1033                     $links_added[$menu_index]++;
1034                 }
1035             }
1036         }
1037
1038         $menu_wrapper =
'';
1039         
for($i = 0; $i < count($menu); $i++){
1040             $menu_wrapper .= <<<EOT
1041                 {$menu[$i]}
1042                 <!--<li
class="dropdown">-->
1043                     <a href=
"#" class="dropdown-toggle" data-toggle="dropdown">{$table_group_name[$i]} <b class="caret"></b></a>
1044                 <!-- <ul
class="dropdown-menu" role="menu">{$menu[$i]}</ul> -->
1045                 <!--</li>-->
1046 EOT;
1047         }
1048
1049         
return $menu_wrapper;
1050     }
1051
1052     #########################################################
1053
1054     function StyleSheet(){
1055         
if(!defined('PREPEND_PATH')) define('PREPEND_PATH', '');
1056         $prepend_path = PREPEND_PATH;
1057
1058         $css_links = <<<EOT
1059
1060             <link rel=
"stylesheet" href="{$prepend_path}resources/initializr/css/bootstrap.css">
1061             <link rel=
"stylesheet" href="{$prepend_path}resources/lightbox/css/lightbox.css" media="screen">
1062             <link rel=
"stylesheet" href="{$prepend_path}resources/select2/select2.css" media="screen">
1063             <link rel=
"stylesheet" href="{$prepend_path}resources/timepicker/bootstrap-timepicker.min.css" media="screen">
1064             <link rel=
"stylesheet" href="{$prepend_path}dynamic.css.php">
1065 EOT;
1066
1067         
return $css_links;
1068     }
1069
1070     #########################################################
1071
1072     function getUploadDir($dir){
1073         
global $Translation;
1074
1075         
if($dir==""){
1076             $dir=$Translation[
'ImageFolder'];
1077         }
1078
1079         
if(substr($dir, -1)!="/"){
1080             $dir.=
"/";
1081         }
1082
1083         
return $dir;
1084     }
1085
1086     #########################################################
1087
1088     function PrepareUploadedFile($FieldName, $MaxSize, $FileTypes =
'jpg|jpeg|gif|png', $NoRename = false, $dir = ''){
1089         
global $Translation;
1090         $f = $_FILES[$FieldName];
1091         
if($f['error'] == 4 || !$f['name']) return '';
1092
1093         $dir = getUploadDir($dir);
1094
1095         
/* get php.ini upload_max_filesize in bytes */
1096         $php_upload_size_limit = trim(ini_get(
'upload_max_filesize'));
1097         $last = strtolower($php_upload_size_limit[strlen($php_upload_size_limit) -
1]);
1098         
switch($last){
1099             
case 'g':
1100                 $php_upload_size_limit *=
1024;
1101             
case 'm':
1102                 $php_upload_size_limit *=
1024;
1103             
case 'k':
1104                 $php_upload_size_limit *=
1024;
1105         }
1106
1107         $MaxSize = min($MaxSize, $php_upload_size_limit);
1108
1109         
if($f['size'] > $MaxSize || $f['error']){
1110             echo error_message(str_replace(
'<MaxSize>', intval($MaxSize / 1024), $Translation['file too large']));
1111             exit;
1112         }
1113         
if(!preg_match('/\.(' . $FileTypes . ')$/i', $f['name'], $ft)){
1114             echo error_message(str_replace(
'<FileTypes>', str_replace('|', ', ', $FileTypes), $Translation['invalid file type']));
1115             exit;
1116         }
1117
1118         $name = str_replace(
' ', '_', $f['name']);
1119         
if(!$NoRename) $name = substr(md5(microtime() . rand(0, 100000)), -17) . $ft[0];
1120
1121         
if(!file_exists($dir)) @mkdir($dir, 0777);
1122
1123         
if(!@move_uploaded_file($f['tmp_name'], $dir . $name)){
1124             echo error_message(
"Couldn't save the uploaded file. Try chmoding the upload folder '{$dir}' to 777.");
1125             exit;
1126         }
1127
1128         @chmod($dir . $name,
0666);
1129         
return $name;
1130     }
1131
1132     #########################################################
1133
1134     function get_home_links($homeLinks, $default_classes, $tgroup =
''){
1135         
if(!is_array($homeLinks) || !count($homeLinks)) return '';
1136
1137         $memberInfo = getMemberInfo();
1138
1139         ob_start();
1140         
foreach($homeLinks as $link){
1141             
if(!isset($link['url']) || !isset($link['title'])) continue;
1142             
if($tgroup != $link['table_group'] && $tgroup != '*') continue;
1143
1144             
/* fall-back classes if none defined */
1145             
if(!$link['grid_column_classes']) $link['grid_column_classes'] = $default_classes['grid_column'];
1146             
if(!$link['panel_classes']) $link['panel_classes'] = $default_classes['panel'];
1147             
if(!$link['link_classes']) $link['link_classes'] = $default_classes['link'];
1148
1149             
if($memberInfo['admin'] || @in_array($memberInfo['group'], $link['groups']) || @in_array('*', $link['groups'])){
1150                 ?>
1151                 <div
class="col-xs-12 <?php echo $link['grid_column_classes']; ?>">
1152                     <div
class="panel <?php echo $link['panel_classes']; ?>">
1153                         <div
class="panel-body">
1154                             <a
class="btn btn-block btn-lg <?php echo $link['link_classes']; ?>" title="<?php echo preg_replace("/&amp;(#[0-9]+|[a-z]+);/i", "&$1;", html_attr(strip_tags($link['description']))); ?>" href="<?php echo $link['url']; ?>"><?php echo ($link['icon'] ? '<img src="' . $link['icon'] . '">' : ''); ?><strong><?php echo $link['title']; ?></strong></a>
1155                             <div
class="panel-body-description"><?php echo $link['description']; ?></div>
1156                         </div>
1157                     </div>
1158                 </div>
1159                 <?php
1160             }
1161         }
1162
1163         $html = ob_get_contents();
1164         ob_end_clean();
1165
1166         
return $html;
1167     }
1168
1169     #########################################################
1170
1171     function quick_search_html($search_term, $label, $separate_dv =
true){
1172         
global $Translation;
1173
1174         $safe_search = html_attr($search_term);
1175         $safe_label = html_attr($label);
1176         $safe_clear_label = html_attr($Translation[
'Reset Filters']);
1177
1178         
if($separate_dv){
1179             $reset_selection =
"document.myform.SelectedID.value = '';";
1180         }
else{
1181             $reset_selection =
"document.myform.writeAttribute('novalidate', 'novalidate');";
1182         }
1183         $reset_selection .=
' document.myform.NoDV.value=1; return true;';
1184
1185         $html = <<<EOT
1186         <div
class="input-group" id="quick-search">
1187             <input type=
"text" id="SearchString" name="SearchString" value="{$safe_search}" class="form-control" placeholder="{$safe_label}">
1188             <span
class="input-group-btn">
1189                 <button name=
"Search_x" value="1" id="Search" type="submit" onClick="{$reset_selection}" class="btn btn-default" title="{$safe_label}"><i class="glyphicon glyphicon-search"></i></button>
1190                 <button name=
"ClearQuickSearch" value="1" id="ClearQuickSearch" type="submit" onClick="\$j('#SearchString').val(''); {$reset_selection}" class="btn btn-default" title="{$safe_clear_label}"><i class="glyphicon glyphicon-remove-circle"></i></button>
1191             </span>
1192         </div>
1193 EOT;
1194         
return $html;
1195     }
1196
1197     #########################################################



Hệ thống xếp lịch học tín chỉ cho sinh viên CNTT trên PHP & MySQL 111.135 lượt xem

Gõ tìm kiếm nhanh...